#version 120

varying vec3 Position;
varying vec3 Normal;
varying vec2 TexCoord;

uniform sampler2D TexMap;

struct LightInfo {
  vec4 Position;
  vec3 La;
  vec3 Ld;
  vec3 Ls;
};
uniform LightInfo Light;// =
/*{
  vec4(0.2, 1.0, 1.0, 0.0),
  vec3(0.5, 0.5, 0.5),
  vec3(1.0, 1.0, 1.0),
  vec3(0.5, 0.5, 0.5)
};*/
//LightInfo Light;

struct MaterialInfo {
  vec3 Ka;
  vec3 Kd;
  vec3 Ks;
  float Shininess;
};
uniform MaterialInfo Material;
//MaterialInfo Material;

void initUniform()
{
  /*
  Light.Position = vec4(0.0, 1.0, 0.0, 0.0);
  Light.La = vec3(0.05, 0.05, 0.05);
  Light.Ld = vec3(0.05, 0.05, 0.05);
  Light.Ls = vec3(0.5, 0.5, 0.5);
  */
  /*
  Material.Ka = vec3(1.0, 1.0, 1.0);
  Material.Kd = vec3(1.0, 1.0, 1.0);
  Material.Ks = vec3(1.0, 1.0, 1.0);
  Material.Shininess = 50;
  */
}

void phongModel(vec3 pos, vec3 norm,
                out vec3 ambient, out vec3 diffuse, out vec3 specular)
{
  
  vec3 n = normalize(norm);
  vec3 s;
  if (Light.Position.w == 0) {
    s = normalize(vec3(Light.Position));
  } else {
    s = normalize(vec3(Light.Position) - Position);
  }
  vec3 v = normalize(-vec3(Position));
  vec3 h = normalize(v + s);
  
  ambient  = Light.La * Material.Ka;
  diffuse  = Light.Ld * Material.Kd *     max(dot(s, n), 0.0);
  specular = Light.Ls * Material.Ks * pow(max(dot(h, n), 0.0),
                                          Material.Shininess  );
}

struct FogInfo {
  float maxDist;
  float minDist;
  vec3 color;
};
FogInfo Fog;

void main()
{
  Fog.minDist = 1000.0;
  Fog.maxDist = 10000.0;
  Fog.color = vec3(0.5,0.6,0.7);
  
  initUniform();  
  float dist = abs( Position.z );
  float maxFogFactor = 0.9;
  float fogFactor = maxFogFactor * (Fog.minDist - dist) /(Fog.minDist - Fog.maxDist);
  fogFactor = clamp( fogFactor, 0.0, maxFogFactor);
  
  vec3 ambient, diffuse, specular;
  vec4 texColour = texture2D(TexMap, TexCoord);
  phongModel(Position, Normal, ambient, diffuse, specular);
  
  
  vec4 ADS = vec4(ambient + diffuse, 1.0) * texColour + 
             vec4(specular, 1.0);
                 
  vec4 finalCol = mix(ADS, vec4(Fog.color, 1.0), fogFactor);
  
  gl_FragColor = finalCol;
}